<?php

class Quad_Cfg_Ini/* implements Quad_Cfg_Interface*/ {
	
	protected $_rawArray = array();
	protected $_nestSeparator;
	protected $_rawContents;
	
	public function __construct($nestSeparator = '.') {
		$this->setNestSeparator($nestSeparator);
	}		

	public function load($filename) {
		if (!is_file($filename)) {
			throw new Quad_Exception("Ini file `$filename` not found.");
		}				
		$ini = parse_ini_file($filename, true);
		if ($ini === false) {
			throw new Quad_Exception("Error parsing ini file `$filename`.");
		}
		$this->_rawArray = $ini;
		$this->interpretVars();
	}	
	
	public function enableObjectNotation() {
		foreach ($this->_rawArray as $section => $values) {
			if (!is_array($values)) {
				$this->$section = $values;
				continue;
			}
			$sectionObject = new stdClass;
			foreach ($values as $key => $value) {
				$this->_addProperty($key, $value, $sectionObject);
			}
			$this->$section = $sectionObject;
		}
		return $this;
	}
	
	public function getNestSeparator() {
		return $this->_nestSeparator;
	}
	
	public function setNestSeparator($sep) {
		$this->_nestSeparator = $sep;
		return $this;
	}
	
	public function getBranchRaw($branchName) {
		return (isset($this->_rawArray[$branchName]) ? $this->_rawArray[$branchName] : false);
	}
	
	public function getBranchesRaw() {
		return $this->_rawArray;
	}
		
	public function getBranches() {
		$vars = get_object_vars($this);
		unset($vars['_rawArray']);
		return $vars;
	}
	
	public function defineAsConstants() {
		foreach ($this->_rawArray as $branch => $vars) {
			foreach ($vars as $var) {
				$name = $branch . '_' . str_replace($this->getNestSepartor(),'_',$var);
				if (!defined($name)) {
					define($name);
				}
			}
		}
	}
	
	public function merge(Quad_Cfg_Interface $cfg) {
		
	}
		
//	protected function _resolveDependencies() {
//		foreach ($this->_rawArray as $section => $values) {
//			if (strpos($section,':') > 1) {
//				$parts = preg_split('/\s*:\s*/',trim($section));
//				foreach ($parts as $part) {
//					if (isset($this->_rawArray[$part])) {
//						$this->_rawArray[$part] = $this->_rawArray[$part] + $values;
//					}
//					else {
//						$this->_rawArray[$part] = $values;
//					}
//				}
//			}
//		}
//	}
	
	
	protected function _addProperty($key, $value, $parent) {
		if (strpos($key,$this->getNestSepartor()) === false) {
			$parent->$key = $value;
		}
		else {
			$parts = explode($this->getNestSepartor(),$key);
			$section = array_shift($parts);
			$newKey = join($this->getNestSepartor(),$parts);
			if (!isset($parent->$section)) {
				$parent->$section = new stdClass;
			}
			self::_addProperty($newKey, $value, $parent->$section);
		}
	}
	
	public function interpretVars() {
		// TODO: add ability to add more known vars
		$this->_knownVars = array(
			'QUAD_DIR' => dirname(__FILE__),
		);
		foreach ($this->_rawArray as $branchName => &$branch) {
			$this->_branch = $branch;
			foreach ($branch as $k => &$v) {
				$v = preg_replace_callback('/(?<!\\\\)%[\w._]+%/', array($this, 'parseOneVar'), $v);				
			}
		}
//Quad_Debug::dumpdie($this->_rawArray);		
		unset($this->_branch);
	}
	
	public function parseOneVar($match) {
		if (isset($this->_knownVars[$match[0]])) {
			return $this->_knownVars[$match[0]];
		}
		elseif (defined($match[0])) {
			return constant($match[0]);
		}		
		elseif (isset($this->_branch[$match[0]])) {
			return $this->_branch[$match[0]];
		}
		return $match[0];
	}
	
	
}